package com.hbnu.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbnu.system.config.BaseException;
import com.hbnu.system.constant.AuthorTypeConstants;
import com.hbnu.system.mapper.PorprojectauthorMapper;
import com.hbnu.system.model.entity.Porproject_registration;
import com.hbnu.system.model.entity.Porprojectauthor;
import com.hbnu.system.model.entity.User;
import com.hbnu.system.service.IPorproject_registrationService;
import com.hbnu.system.service.IProjectQualificationService;
import com.hbnu.system.service.IUserService;
import com.hbnu.system.service.PorprojectauthorService;
import com.hbnu.system.utils.CheckRoleUtil;
import com.hbnu.system.utils.IdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 纵向项目作者服务实现类
 * @author jxl
 */
@Service
public class PorprojectauthorServiceImpl extends ServiceImpl<PorprojectauthorMapper, Porprojectauthor> implements PorprojectauthorService {

    @Autowired
    private IPorproject_registrationService iPorprojectRegistrationService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private CheckRoleUtil checkRoleUtil;

    @Autowired
    private IProjectQualificationService iProjectQualificationService;

    private static final List<String> AUTHOR_TYPE_ORDER = Arrays.asList(
            "1", "2", "3", "4", "5", "6","7", "8", "9", "10"
    );

    // 用于保留两位小数的格式化器
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00");



    /**
     * 添加纵向项目作者
     * @param porprojectauthor 纵向项目作者信息
     * @return 添加操作是否成功
     */
    @Transactional
    @Override
    public boolean addporprojectAuthor(Porprojectauthor porprojectauthor) {

        System.out.println(porprojectauthor);

        // 不使用前端传过来的ID，而是生成一个新的ID
        porprojectauthor.setPorprojecauthorid(null);

        // 检查权限
        Porproject_registration project = iPorprojectRegistrationService.getOne(Wrappers.lambdaQuery(Porproject_registration.class)
                .eq(Porproject_registration::getPRegistrationID, porprojectauthor.getPregistrationid()));
        checkRoleUtil.checkPermissionProject(project.getProjectState());

        //如果是校外作者或者学生，为其生成工号
        if (porprojectauthor.getAuthorType().equals(AuthorTypeConstants.OUT_SCHOOL_AUTHOR)
                ||porprojectauthor.getAuthorType().equals(AuthorTypeConstants.STUDENT)) {
            porprojectauthor.setUserAccount(IdGenerator.generateId());
        }

        if (StrUtil.isEmpty(porprojectauthor.getUserAccount())) {
            throw new BaseException("请输入工号");
        }

        // 检查作者是否已经存在
        Porprojectauthor existingAuthor = getOne(Wrappers.lambdaQuery(Porprojectauthor.class)
                .eq(Porprojectauthor::getPregistrationid, porprojectauthor.getPregistrationid())
                .eq(Porprojectauthor::getUserAccount, porprojectauthor.getUserAccount()));
        if (Objects.nonNull(existingAuthor)) {
            throw new BaseException("不可重复添加");
        }

        // 校验排名
        if (StrUtil.isBlank(porprojectauthor.getRanking())) {
            throw new BaseException("请输入排名");
        }

        // 校验考核系数
        double newAssessment;
        try {
            String assessment = porprojectauthor.getAssessment();
            // 如果考核系数为null或空，默认为0
            if (assessment == null || assessment.trim().isEmpty()) {
                newAssessment = 0.0;
            } else {
                newAssessment = Double.parseDouble(assessment);
            }
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0 - 100范围内");
        }

        String Pscore = "0.00";

        Porproject_registration porprojectRegistration = iPorprojectRegistrationService.getPorproject(porprojectauthor.getPregistrationid());
        if(porprojectRegistration != null){
            int finalValue = (int) porprojectRegistration.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        // 校验总分（只计算已填写考核系数的作者）
        List<Porprojectauthor> authorList = list(Wrappers.lambdaQuery(Porprojectauthor.class)
                .eq(Porprojectauthor::getPregistrationid, porprojectauthor.getPregistrationid()));
        double sum = 0;
        // 只计算已填写考核系数的作者
        for (Porprojectauthor author : authorList) {
            if(!StrUtil.isBlank(author.getAssessment())){
                sum += Double.parseDouble(author.getAssessment());
            }
        }
        if (sum + newAssessment > 100) {
            throw new BaseException("已填写作者考核系数总和大于100!");
        }

        porprojectauthor.setPscore(Pscore);
        // 插入作者信息
        save(porprojectauthor);

        // 维护 ProjectMembers 字段
        updateProjectMembers(project, porprojectauthor);

        return true;
    }

    /**
     * 查询纵向项目的作者
     * @param id 纵向项目ID
     * @return 纵向项目作者列表
     */
    @Override
    public List<Porprojectauthor> porprojectauthor(String id) {
        List<Porprojectauthor> list = baseMapper.selectList(Wrappers.lambdaQuery(Porprojectauthor.class)
                .eq(Porprojectauthor::getPregistrationid, id));
        //按照作者排名排序ranking字段：1，2，3，4
        list.sort(Comparator.comparingInt(p -> Integer.parseInt(p.getRanking())));
        return list;
    }

    /**
     * 修改纵向项目作者
     * @param porprojectauthor 纵向项目作者信息
     * @return 修改操作是否成功
     */
    @Override
    public boolean updateporprojectAuthor(Porprojectauthor porprojectauthor) {
        Porproject_registration project = iPorprojectRegistrationService.getOne(Wrappers.lambdaQuery(Porproject_registration.class)
                .eq(Porproject_registration::getPRegistrationID, porprojectauthor.getPregistrationid()));
        checkRoleUtil.checkPermissionProject(project.getProjectState());

        double newAssessment;
        try {
            String assessment = porprojectauthor.getAssessment();
            // 如果考核系数为null或空，默认为0
            if (assessment == null || assessment.trim().isEmpty()) {
                newAssessment = 0.0;
            } else {
                newAssessment = Double.parseDouble(assessment);
            }
        } catch (NumberFormatException e) {
            throw new BaseException("考核系数格式不正确");
        }
        if (newAssessment > 100 || newAssessment < 0) {
            throw new BaseException("输入数据应在0 - 100范围内");
        }

        String Pscore = "0.00";

        Porproject_registration porprojectRegistration = iPorprojectRegistrationService.getPorproject(porprojectauthor.getPregistrationid());
        System.out.println("porprojectRegistration"+porprojectRegistration);
        if(porprojectRegistration != null){
            int finalValue = (int) porprojectRegistration.getScore();
            // 计算并保留两位小数
            double pscore = finalValue * newAssessment / 100.0;
            Pscore = DECIMAL_FORMAT.format(pscore);
        }

        List<Porprojectauthor> authorList = list(Wrappers.lambdaQuery(Porprojectauthor.class)
                .eq(Porprojectauthor::getPregistrationid, porprojectauthor.getPregistrationid()));
        double sum = 0;
        // 只计算已填写考核系数的作者（排除当前修改的作者）
        for (Porprojectauthor author : authorList) {
            if (!author.getPorprojecauthorid().equals(porprojectauthor.getPorprojecauthorid())) {
                if(!StrUtil.isBlank(author.getAssessment())){
                    sum += Double.parseDouble(author.getAssessment());
                }
            }
        }
        // 检查已填写考核系数的总和是否超过100
        if (sum + newAssessment > 100) {
            throw new BaseException("已填写作者考核系数总和大于100");
        }

        porprojectauthor.setPscore(Pscore);

        baseMapper.updateById(porprojectauthor);

        // 维护 ProjectMembers 字段
        updateProjectMembers(project, porprojectauthor);

        return true;
    }

    /**
     * 删除纵向项目作者
     * @param id 作者ID
     * @return 删除操作是否成功
     */
    @Override
    public boolean deleteporprojectAuthor(String id) {
        Porprojectauthor porprojectauthor = super.getOne(Wrappers.lambdaQuery(Porprojectauthor.class)
                .eq(Porprojectauthor::getPorprojecauthorid, id));
        if (Objects.isNull(porprojectauthor)) {
            throw new BaseException("不存在关联作者");
        }

        Porproject_registration project = iPorprojectRegistrationService.getOne(Wrappers.lambdaQuery(Porproject_registration.class)
                .eq(Porproject_registration::getPRegistrationID, porprojectauthor.getPregistrationid()));
        checkRoleUtil.checkPermissionProject(project.getProjectState());


        baseMapper.deleteById(porprojectauthor);

        // 维护 ProjectMembers 字段
        updateProjectMembers(project, porprojectauthor);

        return true;
    }



    /**
     * 维护 ProjectMembers 字段
     * @param project 纵向项目对象
     * @param porprojectauthor 当前操作的作者
     */
    private void updateProjectMembers(Porproject_registration project, Porprojectauthor porprojectauthor) {
        // 1. 先清空原有字段
        project.setProjectMembers(null);
        iPorprojectRegistrationService.updateById(project);

        // 2. 查询所有作者
        List<Porprojectauthor> allAuthorList = list(Wrappers.lambdaQuery(Porprojectauthor.class)
                .eq(Porprojectauthor::getPregistrationid, porprojectauthor.getPregistrationid()));

        // 3. 按照作者排名ranking排序，ranking是数字，按照数字排序
        allAuthorList.sort(Comparator.comparingInt(p -> Integer.parseInt(p.getRanking())));

        // 4. 获取用户主键ID列表
        List<String> userAccountList = allAuthorList.stream()
                .map(Porprojectauthor::getUserAccount).collect(Collectors.toList());

        List<User> userList = Collections.emptyList();
        if (!userAccountList.isEmpty()) {
            userList = iUserService.list(Wrappers.lambdaQuery(User.class)
                    .in(User::getAccount, userAccountList));
        }

        List<String> uidList = userList.stream()
                .map(User::getUid).collect(Collectors.toList());

        // 5. 拼接字符串并更新字段
        String projectMembers = String.join(",", uidList);
        project.setProjectMembers(projectMembers);
        iPorprojectRegistrationService.updateById(project);
    }
}
